#include <iostream>
#include "stdio.h"
#include "wsdd.nsmap"
#include "plugin/wsseapi.h"
#include "plugin/wsaapi.h"
#include <openssl/rsa.h>
#include "ipconvif.h"
#include "ErrorLog.h"

#include "proxycpp/soapDeviceBindingProxy.h"
#include "proxycpp/soapMediaBindingProxy.h"

using namespace std;

#define MAX_HOSTNAME_LEN 128
#define MAX_LOGMSG_LEN 256

void PrintErr(struct soap *_psoap)
{
    fflush(stdout);
    processEventLog(__FILE__, __LINE__, stdout, "error:%d faultstring:%s faultcode:%s faultsubcode:%s faultdetail:%s", _psoap->error,
                    *soap_faultstring(_psoap), *soap_faultcode(_psoap), *soap_faultsubcode(_psoap), *soap_faultdetail(_psoap));
}

int get_rtsp_url(char *rtspurl1, char *rtspurl2, const char *ip, const char *username, const char *password)
{
    char szHostName[MAX_HOSTNAME_LEN] = {0};

    DeviceBindingProxy proxyDevice;
    MediaBindingProxy proxyMedia;

    strcat(szHostName, "http://");
    strcat(szHostName, ip);
    strcat(szHostName, "/onvif/device_service");

    proxyDevice.soap_endpoint = szHostName;

    soap_register_plugin(proxyDevice.soap, soap_wsse);
    soap_register_plugin(proxyMedia.soap, soap_wsse);

    struct soap *soap = soap_new();

    if (SOAP_OK != soap_wsse_add_UsernameTokenDigest(proxyDevice.soap, NULL, username, password))
    {
        return -1;
    }

    if (SOAP_OK != soap_wsse_add_Timestamp(proxyDevice.soap, "Time", 10))
    {
        return -1;
    }

    _tds__GetCapabilities *tds__GetCapabilities = soap_new__tds__GetCapabilities(soap, -1);
    tds__GetCapabilities->Category.push_back(tt__CapabilityCategory__All);

    _tds__GetCapabilitiesResponse *tds__GetCapabilitiesResponse = soap_new__tds__GetCapabilitiesResponse(soap, -1);

    if (SOAP_OK == proxyDevice.GetCapabilities(tds__GetCapabilities, tds__GetCapabilitiesResponse))
    {
        if (tds__GetCapabilitiesResponse->Capabilities->Media != NULL)
        {
            proxyMedia.soap_endpoint = tds__GetCapabilitiesResponse->Capabilities->Media->XAddr.c_str();
        }
    }
    else
    {
        PrintErr(proxyDevice.soap);
    }

    soap_destroy(soap);
    soap_end(soap);

    if (SOAP_OK != soap_wsse_add_UsernameTokenDigest(proxyMedia.soap, NULL, username, password))
    {
        return -1;
    }

    if (SOAP_OK != soap_wsse_add_Timestamp(proxyMedia.soap, "Time", 10))
    {
        return -1;
    }

    _trt__GetProfiles *trt__GetProfiles = soap_new__trt__GetProfiles(soap, -1);
    _trt__GetProfilesResponse *trt__GetProfilesResponse = soap_new__trt__GetProfilesResponse(soap, -1);

    if (SOAP_OK == proxyMedia.GetProfiles(trt__GetProfiles, trt__GetProfilesResponse))
    {
        _trt__GetStreamUri *trt__GetStreamUri = soap_new__trt__GetStreamUri(soap, -1);
        trt__GetStreamUri->StreamSetup = soap_new_tt__StreamSetup(soap, -1);
        trt__GetStreamUri->StreamSetup->Stream = tt__StreamType__RTP_Unicast;
        trt__GetStreamUri->StreamSetup->Transport = soap_new_tt__Transport(soap, -1);
        trt__GetStreamUri->StreamSetup->Transport->Protocol = tt__TransportProtocol__RTSP;

        _trt__GetStreamUriResponse *trt__GetStreamUriResponse = soap_new__trt__GetStreamUriResponse(soap, -1);

        for (int i = 0; i < trt__GetProfilesResponse->Profiles.size(); i++)
        {
            trt__GetStreamUri->ProfileToken = trt__GetProfilesResponse->Profiles[i]->token;

            if (SOAP_OK != soap_wsse_add_UsernameTokenDigest(proxyMedia.soap, NULL, username, password))
            {
                return -1;
            }

            if (SOAP_OK == proxyMedia.GetStreamUri(trt__GetStreamUri, trt__GetStreamUriResponse))
            {
                std::string url_head = trt__GetStreamUriResponse->MediaUri->Uri.substr(0, trt__GetStreamUriResponse->MediaUri->Uri.find_first_of('/') + 2);
                std::string url_tail = trt__GetStreamUriResponse->MediaUri->Uri.substr(trt__GetStreamUriResponse->MediaUri->Uri.find_first_of('/') + 2);
                std::string rtspUrl = url_head + std::string(username) + ":" + std::string(password) + "@" + url_tail;
                if (i == 0) // main rtsp url
                {
                    processEventLog(__FILE__, __LINE__, stdout, "rtspurl1:%s", rtspUrl.c_str());
                    memcpy(rtspurl1, rtspUrl.c_str(), rtspUrl.size());
                }
                else if (i ==1) // second rtsp url
                {
                    processEventLog(__FILE__, __LINE__, stdout, "rtspurl2:%s", rtspUrl.c_str());
                    memcpy(rtspurl2, rtspUrl.c_str(), rtspUrl.size());
                }
            }
            else
            {
                PrintErr(proxyMedia.soap);
            }
        }
    }
    else
    {
        PrintErr(proxyMedia.soap);
    }

    soap_destroy(soap);
    soap_end(soap);

    return 0;
}

int main()
{
    char buf1[1024] = {0};
    char buf2[1024] = {0};
    int ret = get_rtsp_url(buf1, buf2, "192.21.1.201", "admin", "123cpucpu");
    if (ret != 0)
    {
        std::cout << "not find" << std::endl;
    }

    return 0;
}
